//package com.chenl.provider.util.mybatisFilter;
//
//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
//import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
//import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
//import com.baomidou.mybatisplus.core.toolkit.Wrappers;
//import com.google.common.base.CaseFormat;
//import com.google.common.collect.Maps;
//import java.lang.reflect.Field;
//import java.math.BigDecimal;
//import java.math.BigInteger;
//import java.time.LocalDate;
//import java.time.LocalDateTime;
//import java.time.LocalTime;
//import java.time.format.DateTimeFormatter;
//import java.util.ArrayList;
//import java.util.Arrays;
//import java.util.List;
//import java.util.Map;
//import java.util.Optional;
//import java.util.function.Supplier;
//import org.apache.commons.lang3.StringUtils;
//
//
//public class QueryParamUtils {
//    private static String qpPrefix = "qp-";
//    private static String splitStr = "-";
//    private static final String BRACKETS = "[]";
//    private static final String KEY_IN = "in,notIn";
//
//    public QueryParamUtils() {
//    }
//
//    public static QueryWrapper getEntityWrapper(Map<String, Object> params, Class clz) {
//        QueryWrapper ew = new QueryWrapper();
//        return getEntityWrapper(params, ew, clz);
//    }
//
//    public static QueryWrapper getEntityWrapper(Map<String, Object> params, QueryWrapper ew, Class clz) {
//        params.forEach((k, v) -> {
//            if (k.startsWith(qpPrefix)) {
//                Map<String, String> qpMap = getQueryParamMap(k);
//                String fieldName = (String)qpMap.get("fieldName");
//                String camelFieldName = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, fieldName);
//                if (v != null && StringUtils.isNoneBlank(new CharSequence[]{v.toString()})) {
//                    freshEw(ew, (String)qpMap.get("option"), (String)qpMap.get("fieldName"), formatFieldVal(camelFieldName, v, clz, (String)qpMap.get("option")));
//                }
//            }
//
//        });
//        return ew;
//    }
//
//    public static QueryWrapper getMultiEntityWrapper(Map<String, Object> params, Class entity) {
//        if (entity == null && !params.isEmpty()) {
//            throw new AppException("Query condition matching error,because the entity is null!");
//        } else {
//            Map<String, Class> entities = Maps.newHashMap();
//            entities.put("t1.", entity);
//            return getMultiEntityWrapper(params, (Map)null, (Map)entities);
//        }
//    }
//
//    public static QueryWrapper getMultiEntityWrapper(Map<String, Object> params, Class entity, String defaultPrex) {
//        if (entity == null && !params.isEmpty()) {
//            throw new AppException("Query condition matching error,because the entity is null!");
//        } else {
//            Map<String, Class> entities = Maps.newHashMap();
//            entities.put(Optional.ofNullable(defaultPrex).orElse("t1."), entity);
//            return getMultiEntityWrapper(params, (Map)null, entities, defaultPrex);
//        }
//    }
//
//    public static QueryWrapper getMultiEntityWrapper(Map<String, Object> params, Map<String, String> otherTableFields, Map<String, Class> entities) {
//        Boolean validateEntities = entities.isEmpty() || !entities.containsKey("t1.");
//        if (validateEntities && !params.isEmpty()) {
//            throw new AppException("Query condition matching error,because the entities(t1.) is null!");
//        } else {
//            return getMultiEntityWrapper(params, otherTableFields, entities, "t1.");
//        }
//    }
//
//    public static QueryWrapper getMultiEntityWrapper(Map<String, Object> params, Map<String, String> otherTableFields, Map<String, Class> entities, String defaultPrex) {
//        QueryWrapper ew = new QueryWrapper();
//        String dfPrex = (String)Optional.ofNullable(defaultPrex).orElse("t1.");
//        if (params == null) {
//            return ew;
//        } else if (entities != null && !entities.isEmpty() && entities.containsKey(dfPrex)) {
//            params.forEach((k, v) -> {
//                if (k.startsWith(qpPrefix)) {
//                    Map<String, String> qpMap = getQueryParamMap(k);
//                    if (v != null && StringUtils.isNoneBlank(new CharSequence[]{v.toString()})) {
//                        String fieldName = (String)qpMap.get("fieldName");
//                        String camelFieldName = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, fieldName);
//                        if (otherTableFields != null && !otherTableFields.isEmpty() && otherTableFields.containsKey(camelFieldName)) {
//                            String tableAliasDot = (String)otherTableFields.get(camelFieldName);
//                            Class clzx = (Class)entities.get(tableAliasDot);
//                            String key = tableAliasDot + fieldName;
//                            freshEw(ew, (String)qpMap.get("option"), key, formatFieldVal(camelFieldName, v, clzx, (String)qpMap.get("option")));
//                        } else {
//                            Class clz = (Class)entities.get(dfPrex);
//                            freshEw(ew, (String)qpMap.get("option"), dfPrex + fieldName, formatFieldVal(camelFieldName, v, clz, (String)qpMap.get("option")));
//                        }
//                    }
//                }
//
//            });
//            return ew;
//        } else {
//            throw new AppException("Query condition matching error,because the entities(" + dfPrex + ") is null!");
//        }
//    }
//
//    private static QueryWrapper freshEw(QueryWrapper ew, String option, String fieldName, Object value) {
//        switch (option) {
//            case "eq":
//                ew.eq(fieldName, value);
//                break;
//            case "ne":
//                ew.ne(fieldName, value);
//                break;
//            case "gt":
//                ew.gt(fieldName, value);
//                break;
//            case "ge":
//                ew.ge(fieldName, value);
//                break;
//            case "le":
//                ew.le(fieldName, value);
//                break;
//            case "lt":
//                ew.lt(fieldName, value);
//                break;
//            case "in":
//                if (value instanceof ArrayList) {
//                    ew.in(fieldName, (ArrayList)value);
//                } else {
//                    ew.in(fieldName, new Object[]{value});
//                }
//                break;
//            case "notIn":
//                if (value instanceof ArrayList) {
//                    ew.notIn(fieldName, (ArrayList)value);
//                } else {
//                    ew.notIn(fieldName, new Object[]{value});
//                }
//                break;
//            case "like":
//                ew.like(fieldName, value);
//                break;
//            case "notLike":
//                ew.notLike(fieldName, value);
//                break;
//            case "likeleft":
//                ew.likeLeft(fieldName, value);
//                break;
//            case "likeright":
//                ew.likeRight(fieldName, value);
//                break;
//            case "isNull":
//                ew.isNull(fieldName);
//                break;
//            case "isNotNull":
//                ew.isNotNull(fieldName);
//        }
//
//        return ew;
//    }
//
//    private static Map<String, String> getQueryParamMap(String paramStr) {
//        Map retMap = Maps.newHashMap();
//        paramStr = SQLFilter.sqlInject(paramStr);
//        paramStr = StringUtils.removeStart(paramStr, qpPrefix);
//        String[] params = StringUtils.split(paramStr, splitStr);
//        int len = 2;
//        if (params.length == len) {
//            retMap.put("fieldName", FieldUtils.toDBField(params[0]));
//            retMap.put("option", params[1]);
//        }
//
//        return retMap;
//    }
//
//    private static Object formatFieldVal(String key, Object val, Class tClass, String option) {
//        Field field = getDeclaredField(tClass, key);
//        if (field == null) {
//            StringBuilder sb = (new StringBuilder("==Can't find the type corresponding to the query parameter! key=")).append(key).append(",val=").append(val).append("tClass=").append(tClass);
//            throw new AppException(sb.toString());
//        } else {
//            Class clz = field.getType();
//            String baseType = clz.getTypeName();
//            return castType(baseType, val, option);
//        }
//    }
//
//    public static Field getDeclaredField(Class clazz, String fieldName) {
//        if (ObjectUtils.isNull(new Object[]{clazz, fieldName})) {
//            return null;
//        } else {
//            Field field = null;
//
//            while(clazz != Object.class) {
//                try {
//                    field = clazz.getDeclaredField(fieldName);
//                    return field;
//                } catch (Exception var4) {
//                    clazz = clazz.getSuperclass();
//                }
//            }
//
//            return field;
//        }
//    }
//
//    public static Object castType(Field field, Object val, String option) {
//        return castType(field.getType(), val, option);
//    }
//
//    public static Object castType(Class<?> fieldClass, Object val, String option) {
//        return castType(fieldClass.getTypeName(), val, option);
//    }
//
//    public static Object castType(String fieldNameType, Object val, String option) {
//        if (val != null && !StringUtils.isBlank(val.toString())) {
//            DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//            String valStr = String.valueOf(val);
//            String simpleTypeName = StringUtils.substringAfterLast("." + fieldNameType, ".").toLowerCase();
//            if (StringUtils.isNotBlank(option) && "in,notIn".contains(option) && !simpleTypeName.endsWith("[]")) {
//                simpleTypeName = simpleTypeName + "[]";
//            }
//
//            Object ret;
//            String[] str;
//            switch (simpleTypeName) {
//                case "double":
//                    ret = Double.parseDouble(valStr);
//                    break;
//                case "float":
//                    ret = Float.parseFloat(valStr);
//                    break;
//                case "short":
//                    ret = Short.parseShort(valStr);
//                    break;
//                case "integer":
//                    ret = Integer.parseInt(valStr);
//                    break;
//                case "int":
//                    ret = Integer.parseInt(valStr);
//                    break;
//                case "long":
//                    ret = Long.parseLong(valStr);
//                    break;
//                case "boolean":
//                    ret = Boolean.parseBoolean(valStr);
//                    break;
//                case "double[]":
//                    str = valStr.split(",");
//                    List<Double> listDouble = new ArrayList();
//
//                    for(int i = 0; i < str.length; ++i) {
//                        listDouble.add(Double.parseDouble(str[i]));
//                    }
//
//                    ret = listDouble;
//                    break;
//                case "float[]":
//                    str = valStr.split(",");
//                    List<Float> listFloat = new ArrayList();
//
//                    for(int i = 0; i < str.length; ++i) {
//                        listFloat.add(Float.parseFloat(str[i]));
//                    }
//
//                    ret = listFloat;
//                    break;
//                case "short[]":
//                    str = valStr.split(",");
//                    List<Short> shortList = new ArrayList();
//
//                    for(int i = 0; i < str.length; ++i) {
//                        shortList.add(Short.parseShort(str[i]));
//                    }
//
//                    ret = shortList.isEmpty() ? null : shortList;
//                    break;
//                case "integer[]":
//                    str = valStr.split(",");
//                    List<Integer> listInteger = new ArrayList();
//
//                    for(int i = 0; i < str.length; ++i) {
//                        listInteger.add(Integer.parseInt(str[i]));
//                    }
//
//                    ret = listInteger.isEmpty() ? null : listInteger;
//                    break;
//                case "int[]":
//                    str = valStr.split(",");
//                    List<Integer> listInt = new ArrayList();
//
//                    for(int i = 0; i < str.length; ++i) {
//                        listInt.add(Integer.parseInt(str[i]));
//                    }
//
//                    ret = listInt.isEmpty() ? null : listInt;
//                    break;
//                case "long[]":
//                    str = valStr.split(",");
//                    List<Long> listLong = new ArrayList();
//
//                    for(int i = 0; i < str.length; ++i) {
//                        listLong.add(Long.parseLong(str[i]));
//                    }
//
//                    ret = listLong.isEmpty() ? null : listLong;
//                    break;
//                case "string[]":
//                    str = valStr.split(",");
//                    List<String> listString = new ArrayList();
//
//                    for(int i = 0; i < str.length; ++i) {
//                        listString.add(str[i]);
//                    }
//
//                    ret = listString.isEmpty() ? null : listString;
//                    break;
//                case "bigdecimal":
//                    ret = new BigDecimal(valStr);
//                    break;
//                case "biginteger":
//                    ret = new BigInteger(valStr);
//                    break;
//                case "localdate":
//                    ret = LocalDate.parse(valStr);
//                    break;
//                case "localtime":
//                    ret = LocalTime.parse(valStr);
//                    break;
//                case "localdatetime":
//                    ret = LocalDateTime.parse(valStr, df);
//                    break;
//                default:
//                    ret = val;
//            }
//
//            return ret;
//        } else {
//            return null;
//        }
//    }
//
//    public static QueryWrapper queryWrapper4eq(Supplier<?> po, Map<String, Object> params) {
//        QueryWrapper<?> queryWrapper = Wrappers.query();
//        Field[] baseFields = BasePo.class.getDeclaredFields();
//        Field[] poFields = po.get().getClass().getDeclaredFields();
//        params.forEach((fieldName, val) -> {
//            Optional<Field> field = Arrays.stream(poFields).filter((f) -> {
//                return StringUtils.equals(f.getName(), fieldName);
//            }).findFirst();
//            if (!field.isPresent()) {
//                field = Arrays.stream(baseFields).filter((f) -> {
//                    return StringUtils.equals(f.getName(), fieldName);
//                }).findFirst();
//            }
//
//            if (!field.isPresent()) {
//                throw new AppException("参数错误(不支持以下参数)：" + fieldName, ErrorCode.other("417"));
//            } else {
//                Object object = castType((Field)field.get(), val, "eq");
//                if (object != null) {
//                    String fieldNameUnderline = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, fieldName);
//                    queryWrapper.eq(fieldNameUnderline, object);
//                }
//
//            }
//        });
//        return queryWrapper;
//    }
//
//    public static UpdateWrapper updateWrapper4Map(Supplier<?> po, Long id, Map<String, Object> params) {
//        UpdateWrapper<?> updateWrapper = (UpdateWrapper)Wrappers.update().eq("id", id);
//        String remarks = "remarks";
//        Field[] poFields = po.get().getClass().getDeclaredFields();
//        params.forEach((fieldName, val) -> {
//            if (StringUtils.equals(fieldName, remarks)) {
//                updateWrapper.set(fieldName, (String)val);
//            } else {
//                Optional<Field> field = Arrays.stream(poFields).filter((f) -> {
//                    return StringUtils.equals(f.getName(), fieldName);
//                }).findFirst();
//                if (!field.isPresent()) {
//                    throw new AppException("参数错误(不支持以下参数)：" + fieldName, ErrorCode.other("417"));
//                }
//
//                Object object = castType((Field)field.get(), val, "eq");
//                if (object != null) {
//                    String fieldNameUnderline = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, fieldName);
//                    updateWrapper.set(fieldNameUnderline, object);
//                }
//            }
//
//        });
//        return updateWrapper;
//    }
//}
